package com.itcncp.ucenter.web.controller;
import com.itcncp.common.base.BaseController;
import com.itcncp.common.util.DateUtils;
import com.itcncp.common.util.HttpUtils;
import com.itcncp.common.util.IDCardUtil;
import com.itcncp.common.util.JsonUtils;
import com.itcncp.ucenter.common.ApiConstant;
import com.itcncp.ucenter.common.ApiResult;
import com.itcncp.ucenter.common.ApiResultConstant;
import com.itcncp.ucenter.dao.model.*;
import com.itcncp.ucenter.rpc.api.UserAccountInfoService;
import com.itcncp.ucenter.rpc.api.UserBankInfoService;
import com.itcncp.ucenter.rpc.api.UserCashinOpJnlService;
import com.itcncp.ucenter.rpc.api.UserCustomerInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * Created by shuitcncp on 2016/12/10.
 */
@Controller
@RequestMapping("/account")
@Api(tags = "account",value = "账户信息", description = "账户的基本信息接口",
        produces = "produces",consumes = "consumes",basePath = "/account")

public class UserAccountController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserAccountController.class);

    @Autowired
    private UserCustomerInfoService userCustomerInfoService;
    @Autowired
    private UserAccountInfoService userAccountInfoService;
    @Autowired
    private UserBankInfoService userBankInfoService;
    @Autowired
    private UserCashinOpJnlService userCashinOpJnlService;

    /**
     * 绑定银行卡 操作表名： user_bank_info,user_info
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation("绑定银行卡")
    @RequestMapping(value = "/bindCardNo", method = RequestMethod.POST)
    @ResponseBody
    public Object addBankCard(@RequestParam(name="userId",defaultValue="0",required=true) Long userId,
                               @RequestParam(name = "authName", defaultValue = "", required = true)String authName,
                               @RequestParam(name = "icCard", defaultValue = "", required = true) String icCard,
                              @RequestParam(name = "cardNo", defaultValue = "", required = true) String cardNo,
                              @RequestParam(name = "mobile", defaultValue = "", required = true) String mobile,
                               HttpServletRequest request, HttpServletResponse response) {

        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        //验证手机号的正确性
        if(StringUtils.isEmpty( mobile )){
            return new ApiResult( ApiResultConstant.APP_MOBILE_ERROR);
        }

        if(!IDCardUtil.mobile( mobile )){
            return new ApiResult( ApiResultConstant.APP_MOBILE_ERROR);
        }

        // 校验身份证是否合法
        if (!IDCardUtil.isIdentity(icCard)) {
            return new ApiResult( ApiResultConstant.APP_FAIL_IDCARD );
        }

        //银行卡
        if (StringUtils.isEmpty( cardNo )) {
            return new ApiResult( ApiResultConstant.APP_FAIL_CARDNO );
        }

        //姓名不能为空
        if(StringUtils.isEmpty( authName )){
            return  new ApiResult( ApiResultConstant.APP_NOT_NAME );
        }

        //判断银行卡与手机号是否一致
        UserCustomerInfo userInfo = userCustomerInfoService.selectByPrimaryKey( userId );
        if(null == userInfo){
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        //测试使用，如果是这个手机号则可以绑定其他手机号
        if(!userInfo.getMobile().equals("13761031601")){
            if(!mobile.equals(userInfo.getMobile())){
                return new ApiResult( ApiResultConstant.APP_MOBILE_ERROR );
            }
        }


        //银行卡类型
        Integer cardType = 1;
        //开户银行编号
        String bankId="";


/*
		 * 处理流程：
		 * 1.校验报文，验证身份证号和手机号
		 * 2.验证当前用户上送的当前卡号是否已经绑定
		 * 3.校验当前用户今日的绑定次数（第三方接口返回非成功时累加绑定次数，系统处理异常及绑定成功不做累加），
		 *   超过3次禁止该用户当日的绑定行为
		 * 4.调用第三方接口，查询银行卡信息：
		 *   返回成功，继续后续处理；返回失败，当日绑定次数加1，方法返回；发生异常，方法返回
		 * 5.调用第三方接口，银行卡实名认证：
		 *   返回成功，继续后续处理；返回失败，当日绑定次数加1，方法返回；发生异常，方法返回
		 * 6.将相应数据登记数据库，成功则绑定银行卡成功，失败则登记数据库失败
		 */


        try {


            UserBankInfoExample userBankInfoExample = new UserBankInfoExample();
            userBankInfoExample.createCriteria().andUserIdEqualTo( userId )
                    .andBankcardNoEqualTo( cardNo ).andBankcardStateEqualTo(new Byte("1"));

            Integer isBindCount=  userBankInfoService.countByExample( userBankInfoExample );

            //该卡已经绑定
            if(isBindCount>0){
                return  new ApiResult( ApiResultConstant.APP_EXISTS_CARDNO );
            }

            //绑定验证失败次数
            Integer bankcardBindingCount=0;
            //日期是否为空
            if(null != userInfo.getBankcardBingingDate()){
                //日期是否为当天
               String verityDate =  DateUtils.dateFormat( userInfo.getBankcardBingingDate(),"yyyy-MM-dd" );
               String nowDate = DateUtils.dateFormatNow( "yyyy-MM-dd" );
               if(verityDate.equals( nowDate )){
                   bankcardBindingCount = userInfo.getBankcardBingingCount().intValue();
               }
            }
            //验证当前用户访问次数
            if(bankcardBindingCount>=3){
                return new ApiResult( ApiResultConstant.APP_BIND_COUNT_CARDNO );
            }


            HashMap<String, String> headers = new HashMap<String, String>();

            headers.put("Authorization", "APPCODE " + ApiConstant.QUERY_BANK_VERIFY_APP_CODE);
            HashMap<String, String> querys = new HashMap<String, String>();
            querys.put("bankno", cardNo);

            String bankName="";
            try {
				/*返回报文：
				{
				  "resp": {
				    "code": 0,
				    "desc": "OK"
				  },
				  "data": {
				    "bankno": "6217580100005980644",
				    "bank_id": "01040000",
				    "bank_name": "中国银行",
				    "card_name": "医保联名借记IC卡",
				    "bank_phone": "95566",
				    "card_type": "借记卡"
				  }
				}
				 */
				/*响应码：
					0			OK				成功
					300201		银行卡号码不合法		银行卡号码不合法
				 */
				HttpResponse bankInfoResponse = HttpUtils.doGet(ApiConstant.QUERY_BANK_CARD_HOST,
                        ApiConstant.QUERY_BANK_CARD_METHOD, "GET", headers, querys);

                String jsonResult = EntityUtils.toString(bankInfoResponse.getEntity());

                Map<String,Object> result =  JsonUtils.toMap( jsonResult );
                Map<String,Object> resultHead = JsonUtils.toMap(result.get("resp").toString());
                Integer resultCode= Integer.parseInt( resultHead.get("code").toString());
                if(resultCode!=0){
                    //resultCode==300201
                    //绑定次数加1
                    bankcardBindingCount++;
                    userInfo.setBankcardBingingCount( bankcardBindingCount.byteValue() );
                    userInfo.setBankcardBingingDate(new Date());

                    userCustomerInfoService.updateByPrimaryKeySelective(userInfo);
                    return new ApiResult( ApiResultConstant.APP_FAIL_CARDNO );
                }
                Map<String,Object> resultBody=JsonUtils.toMap( result.get("data").toString() );
                bankName = resultBody.get("bank_name").toString();
                String bankcardType = resultBody.get("card_type").toString();
                bankId = resultBody.get("bank_id").toString();

                //银行卡类型,1-借记卡,2-贷记卡,3-准贷记卡,4-预付费卡
                //数据库对应 银行卡类型, 1-借记卡, 2-贷记卡, 3-准贷记卡, 4-预付费卡 5-其他
                if(bankcardType.trim().contains("借记卡")){ //1-借记卡
                    cardType=1;
                }else if(bankcardType.trim().contains("贷记卡")){ //2-贷记卡
                    cardType=2;
                }else if(bankcardType.trim().contains("准贷记卡")){ //3-准贷记卡
                    cardType=3;
                }else if(bankcardType.trim().contains("预付费卡")){ //4-预付费卡
                    cardType=4;
                }else{
                    cardType=5;
                }

            } catch (Exception e) {
                return new ApiResult( ApiResultConstant.APP_FAIL_ATTEST_CARDNO );
            }

            //5.
            //银行卡实名认证
            querys.clear();
            querys.put("acct_name", authName);
            querys.put("acct_pan", cardNo);
            querys.put("cert_id", icCard);
            querys.put("phone_num", userInfo.getMobile());
            Integer bankcardState = 3;
            try {
				/*返回报文：
				{
				  "resp":{
				    "code":0,
				    "desc":"OK"
				  },
				  "data":{},
				}
				 */
				/*响应码：
					0	OK						信息一致
					4	此卡被没收，请于发卡方联系		此卡被没收，请于发卡方联系
					5	持卡人认证失败				信息不一致
					14	无效卡号					无效卡号
					15	此卡无对应发卡方				此卡无对应发卡方
					21	该卡未初始化或睡眠卡			该卡未初始化或睡眠卡
					34	作弊卡，吞卡				作弊卡，吞卡
					40	发卡方不支持的交易			发卡方不支持的交易
					41	此卡已经挂失				此卡已经挂失
					43	此卡被没收					此卡被没收
					54	该卡已过期					该卡已过期
					57	发卡方不允许此交易			发卡方不允许此交易
					62	受限制的卡					受限制的卡
					75	密码错误次数超限				密码错误次数超限
					96	交易失败，请稍后重试			交易失败，请稍后重试
				 */
                HttpResponse verifiResponse = HttpUtils.doGet(ApiConstant.QUERY_BANK_VERIFI_HOST,
                        ApiConstant.QUERY_BANK_VERIFI_METHOD, "GET",
                        headers, querys);


                String jsonVerifi = EntityUtils.toString(verifiResponse.getEntity());

                Map<String,Object> result =  JsonUtils.toMap( jsonVerifi );
                Map<String,Object> resultHead=JsonUtils.toMap( result.get("resp").toString() );
                Integer resultCode= Integer.parseInt( resultHead.get("code").toString());
                String bankcardStateMsg="";
                switch(resultCode){
				/*
				 * bankcardState:1-卡正常,2-卡异常,3-卡注销
				 */
                    case 0 : bankcardState=1;bankcardStateMsg="信息一致";break;               					//信息一致
                    case 4 : bankcardState=2;bankcardStateMsg="此卡被没收，请于发卡方联系";break;               //此卡被没收，请于发卡方联系
                    case 5 : bankcardState=2;bankcardStateMsg="信息不一致 ";break;               //信息不一致
                    case 14 : bankcardState=2;bankcardStateMsg="无效卡号";break;              //无效卡号
                    case 15 : bankcardState=2;bankcardStateMsg="此卡无对应发卡方";break;              //此卡无对应发卡方
                    case 21 : bankcardState=2;bankcardStateMsg="该卡未初始化或睡眠卡  ";break;               //该卡未初始化或睡眠卡
                    case 34 : bankcardState=2;bankcardStateMsg="作弊卡，吞卡";break;               //作弊卡，吞卡
                    case 40 : bankcardState=2;bankcardStateMsg="发卡方不支持的交易";break;               //发卡方不支持的交易
                    case 41 : bankcardState=2;bankcardStateMsg="此卡已经挂失";break;               //此卡已经挂失
                    case 43 : bankcardState=2;bankcardStateMsg="此卡被没收";break;               //此卡被没收
                    case 54 : bankcardState=2;bankcardStateMsg="该卡已过期   ";break;               //该卡已过期
                    case 57 : bankcardState=2;bankcardStateMsg="发卡方不允许此交易  ";break;               //发卡方不允许此交易
                    case 62 : bankcardState=2;bankcardStateMsg="受限制的卡  ";break;               //受限制的卡
                    case 75 : bankcardState=2;bankcardStateMsg="密码错误次数超限   ";break;               //密码错误次数超限
                    case 96 : bankcardState=2;bankcardStateMsg="交易失败，请稍后重试";break;               //交易失败，请稍后重试
                    default: bankcardState=2;break;

                }
                if(bankcardState!=1){
                    //绑定次数加1
                    bankcardBindingCount++;

                    userInfo.setBankcardBingingCount( bankcardBindingCount.byteValue() );
                    userInfo.setBankcardBingingDate(new Date());

                    userCustomerInfoService.updateByPrimaryKeySelective(userInfo);

                    return new ApiResult( ApiResultConstant.APP_FAIL_ATTEST_CARDNO );
                }

            } catch (Exception e) {
                return new ApiResult( ApiResultConstant.APP_FAIL_ATTEST_CARDNO);
            }

            // 调用service
            UserBankInfo userBankInfo =new UserBankInfo();
            userBankInfo.setUserId( userId );
            userBankInfo.setBankcardNo( cardNo );

            String  bankIdtemp = bankId.toString().replace("\"","");
            bankIdtemp = bankIdtemp.replaceAll("0*$","");
            userBankInfo.setBankId(bankIdtemp);

            userBankInfo.setBankName( bankName.replace("\"",""));
            //卡类型 银行卡类型, 1-借记卡, 2-贷记卡, 3-准贷记卡, 4-预付费卡  5-其他
            userBankInfo.setBankcardType( cardType.byteValue() );
            //银行卡状态
            //银行卡状态 1、卡正常 2、卡异常 3、卡注销
            userBankInfo.setBankcardState(bankcardState.byteValue());
            //身份证
            userBankInfo.setRemark( icCard );
            userBankInfo.setCreateTime( new Date(  ) );
            userBankInfo.setUpdateTime( new Date(  ) );
            //绑定银行卡备注
            userBankInfo.setRemark(authName+","+icCard+","+mobile);


            //更新用户个人信息
            UserCustomerInfo userCustomerInfo = new UserCustomerInfo();
            userCustomerInfo.setAgentName(authName);
            userCustomerInfo.setAgentIdType(new Byte("1"));
            userCustomerInfo.setAgentIdNum(icCard);
            userCustomerInfo.setUserId(userInfo.getUserId());
            userCustomerInfoService.updateByPrimaryKeySelective(userCustomerInfo);


            Integer total =  userBankInfoService.addUserBarkInfo( userBankInfo );

            if(total == 1){
                return  new ApiResult( ApiResultConstant.SUCCESS );
            }else if(total==0){
                return  new ApiResult( ApiResultConstant.APP_EXISTS_CARDNO);
            }

        } catch (Exception e) {
            return new ApiResult( ApiResultConstant.APP_FAIL_ATTEST_CARDNO );
        }

        return new ApiResult( ApiResultConstant.FAILED);
    }

    /**
     * 银行卡列表
     * @return
     */
    @ApiOperation("银行卡列表")
    @RequestMapping(value = "/findBankCard", method = RequestMethod.POST)
    @ResponseBody
    public Object findBankCard(HttpServletRequest request,
                               @RequestParam(required = false, defaultValue = "0", value = "userId") Long userId){

        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        UserBankInfoExample userBankInfoExample = new UserBankInfoExample();
        userBankInfoExample.or().andUserIdEqualTo( userId ).andBankcardStateEqualTo(new Byte("1"));

        List<UserBankInfo> list = userBankInfoService.selectByExample( userBankInfoExample );

        return new ApiResult(ApiResultConstant.SUCCESS,list);
    }


    /**
     * 删除银行卡
     * @return
     */
    @ApiOperation("删除银行卡")
    @RequestMapping(value = "/delBankCard", method = RequestMethod.POST)
    @ResponseBody
    public Object delBankCard(HttpServletRequest request,
                               @RequestParam(required = false, defaultValue = "0", value = "userId") Long userId,
                               @RequestParam(required = false, defaultValue = "", value = "bankcardNo") String bankcardNo){

        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }


        UserBankInfo userBankInfo = new UserBankInfo();
        userBankInfo.setBankcardNo(bankcardNo);
        userBankInfo.setUserId(userId);
        userBankInfo.setBankcardState(new Byte("3"));


        Integer result = userBankInfoService.updateByPrimaryKeySelective(userBankInfo);

        if(result>0){
            return new ApiResult(ApiResultConstant.SUCCESS);
        }

        return new ApiResult(ApiResultConstant.FAILED);

    }

    /**
     * 用户提现 操作表名：user_cashin_op_his TODO
     *
     * @param request
     * @param response
     * @return
     */
    @ApiOperation("用户提现")
    @RequestMapping(value = "/withdrawals", method = RequestMethod.POST)
    @ResponseBody
    public Object withdrawals(HttpServletRequest request, HttpServletResponse response,
                              @RequestParam(required = false, defaultValue = "0", value = "userId") Long userId,
                              @RequestParam(required = false, defaultValue = "0", value = "amount") BigDecimal amount,
                              @RequestParam(required = false, defaultValue = "", value = "bankcardNo") String bankcardNo,
                              @RequestParam(required = false, defaultValue = "", value = "bankId") String bankId,
                              @RequestParam(required = false, defaultValue = "", value = "authName") String authName,
                              @RequestParam(required = false, defaultValue = "", value = "bankcardType") Integer bankcardType) {

        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        UserAccountInfo userAccountInfo = userAccountInfoService.withdrawals(userId,amount,bankcardNo,bankId,authName,bankcardType);

        if(null != userAccountInfo){
            return new ApiResult( ApiResultConstant.SUCCESS,userAccountInfo);
        }

        return new ApiResult( ApiResultConstant.FAILED);
    }

    /**
     * 提现记录列表 查询表名：user_cashin_op_his
     *
     * @param request
     * @return
     */
    @ApiOperation("提现记录列表")
    @RequestMapping(value = "/findWithdrawals", method = RequestMethod.POST)
    @ResponseBody
    public Object findWithdrawals(HttpServletRequest request,
                               @RequestParam(required = false, defaultValue = "0", value = "userId") Long userId,
                                  @RequestParam(required = false, defaultValue = "0", value = "pageSize") int pageSize,
                                  @RequestParam(required = false, defaultValue = "5", value = "pageIndex") int pageIndex,
                               @RequestParam(required = false, defaultValue = "", value = "search") String search) {
        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        UserCashinOpJnlExample userCashinOpJnlExample = new UserCashinOpJnlExample();
        userCashinOpJnlExample.or().andUserIdEqualTo( userId );

        //排序
        userCashinOpJnlExample.setOrderByClause("cashin_no desc");

        List<UserCashinOpJnl> list = userCashinOpJnlService.selectByExampleForStartPage(userCashinOpJnlExample, pageIndex,pageSize);


        return new ApiResult(ApiResultConstant.SUCCESS,list);
    }

    /**
     * 用户资金
     * @param request
     * @return
     */
    @ApiOperation("用户资金")
    @RequestMapping(value = "/wallet", method = RequestMethod.POST)
    @ResponseBody
    public Object findWithdrawals(HttpServletRequest request,
                                  @RequestParam(required = false, defaultValue = "0", value = "userId") Long userId) {

        // 检查用户Id是否正确
        if (userId<=0) {
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        UserAccountInfo userAccountInfo = userAccountInfoService.selectByPrimaryKey( userId );

        if(null != userAccountInfo){

            return new ApiResult( ApiResultConstant.SUCCESS ,userAccountInfo);

        }else {

            return new ApiResult( ApiResultConstant.FAILED);

        }

    }



}